package com.auntvt.timo.jpax.core.quick.matcher;

import com.auntvt.timo.jpax.core.interfaces.JpaxFunction;
import com.auntvt.timo.jpax.core.quick.enums.MatcherJoinType;
import com.auntvt.timo.jpax.core.utils.LambdaUtil;
import org.springframework.dao.InvalidDataAccessApiUsageException;

import java.util.function.Consumer;

/**
 * QuickSpecification 条件匹配器抽象类
 *
 * @author 小懒虫 <auntvt@163.com>
 * @date 2021/7/31
 */
public class LambdaQuickMatcher<T> extends AbstractMatcher<T, LambdaQuickMatcher<T>, JpaxFunction<T, ?>> {

    /**
     * 带参构造函数，必须传入实体类对象
     *
     * @param bean Bean对象
     */
    public LambdaQuickMatcher(Object bean) {
        super(bean);
    }

    /**
     * 子类创建一个本身的实例对象
     */
    @Override
    protected LambdaQuickMatcher<T> instance(Object bean) {
        return new LambdaQuickMatcher<>(bean);
    }

    /**
     * 将字段名称对象格式化为字符串类型，由子类负责实现
     *
     * @param fieldName 字段名称对象
     * @return 字段名
     */
    @Override
    protected String fieldNameToString(JpaxFunction<T, ?> fieldName) {
        String name = LambdaUtil.getFieldName(fieldName);
        if (name == null || name.trim().length() == 0) {
            throw new InvalidDataAccessApiUsageException("字段系列化失败，无法获得字段名称！");
        }
        return name;
    }

    /**
     * 表关联条件匹配（默认内连接INNER）
     *
     * @param fieldName 字段名
     * @param consumer  可使用箭头函数
     * @param <JT>      关联查询的实体类
     * @return this
     */
    public <JT> LambdaQuickMatcher<T> withJoinMatcher(JpaxFunction<T, ?> fieldName, Consumer<LambdaQuickMatcher<JT>> consumer) {
        return super.withJoinMatcher(fieldName, consumer);
    }

    /**
     * 表关联条件匹配
     *
     * @param fieldName       字段名
     * @param matcherJoinType 条件类型
     * @param consumer        可使用箭头函数
     * @param <JT>            关联查询的实体类
     * @return this
     */
    public <JT> LambdaQuickMatcher<T> withJoinMatcher(JpaxFunction<T, ?> fieldName, MatcherJoinType matcherJoinType, Consumer<LambdaQuickMatcher<JT>> consumer) {
        return super.withJoinMatcher(fieldName, matcherJoinType, consumer);
    }

    /**
     * 转换为QuickMatcher匹配器
     *
     * @return QuickMatcher<T>
     */
    public QuickMatcher<T> quickMatcher() {
        return this.convert(new QuickMatcher<>(params));
    }
}
